package com.chaos.auth.config.grant.converter;


import com.chaos.auth.config.grant.converter.helper.OAuth2EndpointHelper;
import com.chaos.auth.config.grant.converter.para.AdminPhoneOAuth2ParameterNames;
import com.chaos.auth.config.grant.grant.GrantType;
import com.chaos.auth.config.grant.token.AdminPasswordAuthenticationToken;
import com.chaos.auth.config.grant.token.AdminPhoneAuthenticationToken;
import com.chaos.framework.model.enums.ResultEnum;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;

public class AdminPhoneAuthenticationConverter implements AuthenticationConverter {
    @Override
    public Authentication convert(HttpServletRequest request) {
        String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
        if (!GrantType.ADMIN_PHONE.getValue().equals(grantType)) {
            return null;
        }
        Authentication clientPrincipal = SecurityContextHolder.getContext().getAuthentication();
        MultiValueMap<String, String> parameters = OAuth2EndpointHelper.getParameters(request);

        String phone = parameters.getFirst(AdminPhoneOAuth2ParameterNames.PHONE);
        if (!StringUtils.hasText(phone) ||
                parameters.get(AdminPhoneOAuth2ParameterNames.PHONE).size() != 1) {
            OAuth2EndpointHelper.throwError(ResultEnum.INVALID_REQUEST.getCode(), ResultEnum.INVALID_REQUEST.getMsg() + ":" + AdminPhoneOAuth2ParameterNames.PHONE);

        }
        String captcha = parameters.getFirst(AdminPhoneOAuth2ParameterNames.CAPTCHA);

        Map<String, Object> additionalParameters = new HashMap<>();
        parameters.forEach((key, value) -> {
            if (!key.equals(OAuth2ParameterNames.GRANT_TYPE) &&
                    !key.equals(OAuth2ParameterNames.CLIENT_ID) &&
                    !key.equals(AdminPhoneOAuth2ParameterNames.PHONE) &&
                    !key.equals(AdminPhoneOAuth2ParameterNames.CAPTCHA)) {
                additionalParameters.put(key, value.get(0));
            }
        });

        return new AdminPhoneAuthenticationToken(phone, captcha, clientPrincipal, additionalParameters);

    }
}